package com.tourism.service.impl;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tourism.core.common.exception.CustomException;
import com.tourism.core.common.utils.ResultCodeEnum;
import com.tourism.core.security.util.SecurityHolderUtils;
import com.tourism.domain.dto.menu.MenuQueryDTO;
import com.tourism.domain.entity.Menu;
import com.tourism.mapper.MenuMapper;
import com.tourism.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 菜单服务实现类
 *
 * @author lucky
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu>
        implements MenuService {

    @Override
    public boolean removeBatchByIds(Collection<?> list) {
        list.forEach(item -> {
            if(item instanceof Long id){
                if (hasChildren(id)){
                    throw new CustomException(ResultCodeEnum.NODE_HAS_CHILDREN);
                }
            }
        });
        return super.removeBatchByIds(list);
    }

    @Override
    public List<Menu> getMenus(MenuQueryDTO menuQueryDTO) {
        // 查询参数
        String name = menuQueryDTO.getName();
        Integer status = menuQueryDTO.getStatus();

        // 构建查询条件
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.like(StrUtil.isNotBlank(name), Menu::getName, name);
        lqw.eq(status != null, Menu::getStatus, status);

        // 排序
        lqw.orderByAsc(Menu::getSort, Menu::getUpdateTime);

        // 查询
        List<Menu> menuList = list(lqw);

        // 构建菜单树
        return buildMenuTree(menuList);
    }

    @Override
    public List<Menu> getMenuNav() {
        // 获取用户菜单
        List<Menu> menuList = baseMapper.getMenusByUserId(SecurityHolderUtils.getUserId());

        // 过滤掉按钮
        List<Menu> menuNav = menuList.stream().filter(menu -> menu.getType() != 3).toList();

        // 返回菜单树
        return buildMenuTree(menuNav);
    }


    @Override
    public Set<String> getAuth() {
        List<Menu> menuList = baseMapper.getMenusByUserId(SecurityHolderUtils.getUserId());
        return menuList.stream().map(Menu::getPermission).collect(Collectors.toSet());
    }

    /**
     * 构建菜单树
     *
     * @param menuList 菜单集合
     * @return 菜单树
     */
    private List<Menu> buildMenuTree(List<Menu> menuList) {
        // 没有菜单直接返回
        if (CollectionUtils.isEmpty(menuList)) {
            return new ArrayList<>();
        }

        // 创建Map便于查找
        Map<Long, Menu> menuMap = menuList.stream()
                .collect(Collectors.toMap(Menu::getId, menu -> menu));

        // 关联父子关系并找出根节点
        List<Menu> rootNodes = new ArrayList<>();

        for (Menu menu : menuList) {
            Long parentId = menu.getParentId();
            Menu parent = menuMap.get(parentId);

            if (parent != null) {
                // 有父节点，建立父子关系
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(menu);
            } else {
                // 没有父节点或父节点不在当前列表中，作为根节点
                rootNodes.add(menu);
            }
        }

        return rootNodes;
    }


    /**
     * 判断是否存在子菜单
     *
     * @param id 菜单ID
     * @return 是否存在子菜单
     */
    private boolean hasChildren(Long id) {
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getParentId, id);

        return count(lqw) > 0;
    }
}




